/*
 * Copyright (C) 2025 Tsingteng MicroSystem
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/**
 * @file nci_ce_impl_tmsnci.cpp
 * @brief CE部分接口实现
 */

#include "nci_ce_impl_tmsnci.h"
#include "nfc_log_api.h"
#include "nfa_routing.h"
#include "nfa_ee.h"
#include "nfc_sdk_common.h"

namespace OHOS {
namespace NFC {
namespace NCI {

NciCeImplTmsNci::NciCeImplTmsNci() {

}

NciCeImplTmsNci &NciCeImplTmsNci::GetInstance() {
    static NciCeImplTmsNci impl;
    return impl;
}

void NciCeImplTmsNci::SetCeHostListener(std::weak_ptr<ICeHostListener> listener) {
    this->mCeListener = listener;
}
bool NciCeImplTmsNci::ComputeRoutingParams(int defaultPaymentType) {
    uint8_t route = NCI_ROUTE_DH_ID;
    if (defaultPaymentType == static_cast<int>(KITS::DefaultPaymentType::TYPE_ESE)) {
        route = nfa_ee_get_nfcee_id(NCI_NFCEE_ESE1);
    } else if (route == static_cast<int>(KITS::DefaultPaymentType::TYPE_UICC)) {
        route = nfa_ee_get_nfcee_id(NCI_NFCEE_SIM1);
    }

    nfa_routing_set_user_route(USR_ROUTE_TYPE_AID, route, NCI_INVALID_POWER_STATE);
    nfa_routing_set_user_route(USR_ROUTE_TYPE_SYS_CODE, route, NCI_INVALID_POWER_STATE);
    nfa_routing_set_user_route(USR_ROUTE_TYPE_ISODEP, route, NCI_INVALID_POWER_STATE);
    nfa_routing_set_user_route(USR_ROUTE_TYPE_OFFHOST, route, NCI_INVALID_POWER_STATE);
    nfa_routing_set_user_route(USR_ROUTE_TYPE_NFCF, route, NCI_INVALID_POWER_STATE);

    return true;
}
bool NciCeImplTmsNci::CommitRouting() {
    tNCI_STATUS ret = nfa_routing_commit();
    if (ret != NCI_STATUS_OK) {
        NFCLOG_E("nfa_routing_commit failed, ret=%d", ret);
    }
    return ret == NCI_STATUS_OK;
}
bool NciCeImplTmsNci::SendRawFrame(std::string &hexCmdData) {
    uint16_t length = KITS::NfcSdkCommon::GetHexStrBytesLen(hexCmdData);
    uint8_t data[length];
    for (uint32_t i = 0; i < length; i++) {
        data[i] = KITS::NfcSdkCommon::GetByteFromHexStr(hexCmdData, i);
    }
    tNCI_STATUS ret = nfa_ce_transmit(data, length);
    if (ret != NCI_STATUS_OK) {
        NFCLOG_E("nfa_ce_transmit failed, ret=%d", ret);
    }
    return ret == NCI_STATUS_OK;
}
bool NciCeImplTmsNci::AddAidRouting(const std::string &aidStr, int route, int aidInfo, int power) {
    std::vector<unsigned char> aidBytes;
    KITS::NfcSdkCommon::HexStringToBytes(aidStr, aidBytes);
    size_t aidLen = aidBytes.size();

    tNCI_STATUS ret = nfa_routing_add_aid(route, power, static_cast<uint8_t*>(aidBytes.data()), aidLen, aidInfo);
    if (ret != NCI_STATUS_OK) {
        NFCLOG_E("nfa_routing_add_aid failed, ret=%d", ret);
    }
    return ret == NCI_STATUS_OK;
}
bool NciCeImplTmsNci::ClearAidTable() {
    tNCI_STATUS ret = nfa_routing_clear(NCI_ROUTING_ENTRY_AID);
    if (ret != NCI_STATUS_OK) {
        NFCLOG_E("nfa_routing_clear failed, ret=%d", ret);
    }
    return ret == NCI_STATUS_OK;
}
std::string NciCeImplTmsNci::GetSimVendorBundleName() {
    return "";
}

void NciCeImplTmsNci::CeEventCallback(tNCI_CE_EVT event, tNCI_CE_INFO *p_info) {
    NFCLOG_I("enter, event=%d", event);
    if (mCeListener.expired()) {
        NFCLOG_E("mCeListener is null");
        return;
    }
    switch (event) {
        case NCI_CE_EVT_FIELD_INFO:
            if (p_info->field_on) {
                mCeListener.lock()->FieldActivated();
            } else {
                mCeListener.lock()->FieldDeactivated();
            }
            break;
        case NCI_CE_EVT_ACTIVATED:
            mCeListener.lock()->OnCardEmulationActivated();
            break;
        case NCI_CE_EVT_DEACTIVATE:
            mCeListener.lock()->OnCardEmulationDeactivated();
            break;
        case NCI_CE_EVT_DATA: {
            const uint8_t *p_data = p_info->rcv.data.buf;
            uint16_t data_len =  p_info->rcv.data.len;
            std::vector<uint8_t> data(p_data, p_data + data_len);
            mCeListener.lock()->OnCardEmulationData(data);
        }   break;
        default:
            NFCLOG_E("unknown event=%d", event);
            break;
    }
}

} // namespace NCI
} // namespace NFC
} // namespace OHOS